#!/usr/bin/env node
import select from '@inquirer/select';
import chalk from 'chalk';
import figlet from 'figlet';
import {existsSync, readFileSync, writeFileSync} from 'fs';
import input from '@inquirer/input';
import inquirer from 'inquirer';
import {createSpinner} from 'nanospinner';
import {download} from 'obtain-git-repo';
import path from 'path';
import {fileURLToPath} from 'url';
import {rm} from 'fs/promises'
import { rimraf, rimrafSync, } from 'rimraf'
const templateMap = {
  vue2PC: 'https://gitee.com/wzyk/vue2-pc-template.git',
  vue2H5: 'https://gitee.com/wzyk/vue2-h5-template.git',
  vue2UniAppH5: 'https://gitee.com/wzyk/vue2-uniapp-h5-template.git',
  vue2xiaochengxu: 'https://gitee.com/wzyk/vue2-xiaochengxu-template.git',
  vue2UniAppxiaochengxu: 'https://gitee.com/wzyk/vue2-uniapp-xiaochengxu-template.git',
  vue3PC: 'https://gitee.com/wzyk/vue3-pc-template.git',
  vue3H5: 'https://gitee.com/wzyk/vue3-h5-template.git',
  vue3Admin: 'https://gitee.com/wzyk/vue3-admin-template.git',
  vue3daping: 'https://gitee.com/wzyk/vue3-daping-template.git',
  vue2daping: 'https://gitee.com/wzyk/vue2-daping-template.git'
};

const dependenciesMap = {
  vue2: [
    {name: 'lodash', value: 'lodash'},
    {name: 'qs', value: 'qs'},
    {name: 'xgplayer', value: 'xgplayer'},
    {name: 'dayjs', value: 'dayjs'},
    {name: 'vue-wait', value: 'vue-wait'},
    {name: 'vue-waterfall2', value: 'vue-waterfall2@1.10.5'}
  ],
  vue3: [
    {name: 'lodash', value: 'lodash'},
    {name: 'dayjs', value: 'dayjs'},
    {name: 'qs', value: 'qs'},
    {name: 'xgplayer', value: 'xgplayer'},
    {name: 'vue-wait', value: 'vue-wait'},
    {name: 'vue-waterfall2', value: 'vue-waterfall2@latest'}
  ]
};

function getVersion() {
  const dirname = path.dirname(fileURLToPath(import.meta.url));
  const pakJsonPath = path.resolve(dirname, '../','package.json');
  if (existsSync(pakJsonPath)) {
    const pakJson = JSON.parse(readFileSync(pakJsonPath, 'utf-8'));
    return pakJson.version;
  }
}

function printFigletText(text) {
  return new Promise((resolve, reject) => {
    figlet(text, (err, data) => {
      if (err) {
        reject(err);
      } else {
        console.log(data);
        resolve();
      }
    });
  });
}

async function downloadTemplate(url, dirname) {
  return new Promise((resolve, reject) => {
    download(`direct:${url}`, dirname, {clone: true}, (err) => {
      if (err) {
        reject(err);
      } else {
        resolve();
      }
    });
  });
}


async function writeDependenciesToPackageJson(dirname, dependencies) {
  return new Promise((resolve, reject) => {
    const packageJsonPath = path.join(dirname, 'package.json');

    // 读取现有的 package.json 文件
    let packageJson = {};
    if (existsSync(packageJsonPath)) {
      packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
    }

    // 确保 package.json 包含 dependencies 字段
    packageJson.dependencies = packageJson.dependencies || {};

    // 将选择的依赖加入 dependencies
    dependencies.forEach(dep => {
      const [name, version = 'latest'] = dep.split('@');
      packageJson.dependencies[name] = version;
    });

    // 将修改后的内容写回 package.json
    writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8');
    resolve()
  })

}

function selectVueVersion() {
  return select({
    message: '请选择vue版本',
    choices: [
      {name: 'vue2', value: 'vue2'},
      {name: 'vue3', value: 'vue3'}
    ]
  });
}

function selectTemplateType(vueVersion) {
  const choices = vueVersion === 'vue2' ? [
    {name: 'PC', value: 'PC'},
    {name: 'H5', value: 'H5'},
    {name: 'UniAppH5', value: 'UniAppH5'},
    {name: '大屏', value: 'daping'},
    // { name: '小程序', value: 'xiaochengxu' },
    {name: 'UniApp小程序', value: 'UniAppxiaochengxu'}
  ] : [
    {name: '后台', value: 'Admin'},
    {name: 'PC', value: 'PC'},
    {name: 'H5', value: 'H5'},
    {name: '大屏', value: 'daping'}
  ];

  return select({
    message: '请选择模板类型',
    choices
  });
}

 async function selectDependencies(vueVersion, templateType) {
  let choices = []
  const exclude = ['vue-waterfall2', 'vue-wait', 'xgplayer']
  if (templateType.includes('xiaochengxu')) {
    choices = dependenciesMap[vueVersion].filter(item => !exclude.includes(item.name))
  } else {
    choices = dependenciesMap[vueVersion];
  }

   const { dependencies } = await inquirer.prompt({
     name: 'dependencies',
     type: 'checkbox',
     message: '请选择要安装的依赖',
     choices
   });
   return dependencies;

}

async function run() {
  const version = getVersion() || '获取版本失败';
  const args = process.argv.slice(2);

  if (args.includes('--version') || args.includes('-v')) {
    console.log(chalk.green(`v${version}`));
    return;
  }

  try {
    await printFigletText('wzyk');
    console.log(chalk.green('欢迎使用万章盈科前端脚手架'));

    const dirname = await input({
      message: '请输入目录名',
      default: 'wzyk'
    })

    if (existsSync(dirname)) {
      console.log(chalk.redBright('目录已经存在'));
      return;
    }

    const vueVersion = await selectVueVersion();
    const templateType = await selectTemplateType(vueVersion);
    const dependencies = await selectDependencies(vueVersion, templateType);
    const url = templateMap[`${vueVersion}${templateType}`];

    const spinner = createSpinner('开始下载...').start();

    try {
      await downloadTemplate(url, dirname);
      rimrafSync(path.join(dirname, '.git'))
      // await rm(path.join(dirname, '.git'), {recursive: true, force: true});
      spinner.success({text: '项目创建成功'});

      if (dependencies.length > 0) {
        await writeDependenciesToPackageJson(dirname, dependencies);
      }
      console.log(chalk.white(`cd ${dirname}`));
      console.log(chalk.white('pnpm i'));
      console.log(chalk.white('pnpm run dev'));
    } catch (error) {
      spinner.error({text: '下载失败'});
      console.error(error);
    }

  } catch (error) {
    console.error(chalk.red('运行出错：'), error);
  } finally {
    process.exit(0);
  }
}

run();
